home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / cc02.zip / CFLOW.C < prev    next >
Text File  |  1985-08-11  |  6KB  |  325 lines

  1.  
  2. /*
  3. **   CFLOW.C : find module call structure of c program
  4. **   refer to cflow.doc for how to use
  5. **                     Mark Ellington
  6. **                    05-27-84
  7. */
  8.  
  9. #define TRUE    1
  10. #define    FALSE    0
  11. #define    ERROR    -1
  12. #define    EOF    -1    
  13.  
  14. #include printf.c
  15. #include b:cflolib.c80   /* not needed with BDS? */ 
  16.  
  17. int fptr;       /* input file pointer */ 
  18. int level;      /* keep track of level of open "{"s */
  19. char name[100]; /* module name buffer */
  20.  
  21. char ins[100];  /* source input line buffer */
  22. int curchar;    /* current character in input line buffer
  23.            array subscript */     
  24.  
  25. main(argc,argv)
  26. int argc; char *argv[];
  27. {
  28.  
  29.     printf("\nCFLOW --> function declarations and calls in C source");
  30.     printf("\n by Mark Ellington"); 
  31.  
  32.     if (argc != 2) {
  33.         printf("\nusage: cflow [infilename.ext] "); 
  34.                 exit();
  35.     }
  36.  
  37.     if ((fptr = fopen(argv[1],"r")) == FALSE) {
  38.         printf("\nCan't open %s\n",argv[1]);
  39.         exit();
  40.     }
  41.  
  42.     printf("\nSource file: %s",argv[1]);
  43.  
  44.     modules(); 
  45.  
  46.     fclose(fptr);
  47. }
  48.  
  49.  
  50. modules()    /* find function declarations and calls */
  51. {
  52.     int j;
  53.     char c;
  54.     int incom;    /* comment flag */
  55.     int decl;    /* module declaration line flag */
  56.     int lastlin;    /* last line of file flag */
  57.     int quoted;    /* within " quotes */
  58.     int header;    /* within function header (before 1st '{') */
  59.  
  60.     incom = lastlin = quoted  = header = FALSE;
  61.  
  62.     level = 0;
  63.  
  64.     do {
  65.  
  66.         lastlin = fgets();    /* read a line of source */
  67.         
  68.         decl = FALSE;  /* assume nothing */
  69.         curchar = 0;
  70.         while (curchar < 100) {/* read for significant characters */
  71.  
  72.             if (skipline()) break;
  73.  
  74.             quotes();    /* skip single quoted character */
  75.  
  76.             incom = comment(incom);    /* true if in comment */
  77.  
  78.             c = ins[curchar];
  79.         
  80.             /* read for significant characters */
  81.  
  82.             if (!incom) {
  83.  
  84.                 /* skip double quoted strings */
  85.             
  86.                 if (c == '\042') quoted = !quoted;
  87.                 
  88.                 if (!quoted) {
  89.             
  90.                     switch(c) { 
  91.  
  92.                     case '{' :    
  93.                         level++;
  94.                         header = FALSE;
  95.                         break;
  96.  
  97.                     case '}' :    
  98.                         level--;
  99.                         break;    
  100.  
  101.                     /* "(" always follows function call */
  102.                             /* or declaration */
  103.             
  104.                     case '(' :    
  105.  
  106.                     if (!ischar(ins[curchar-1])) 
  107.                         break;
  108.                     lookbak(curchar);
  109.                     j = modname();
  110.                     if (!j) break;
  111.                     else decl = TRUE;
  112.                     if (j == 2) 
  113.                         header = TRUE;    
  114.                     break;
  115.  
  116.  
  117.                               default : 
  118.                           break;
  119.                     }
  120.                 }
  121.             }
  122.         
  123.             ++curchar;     /* next character */
  124.         }
  125.         
  126.             /* display argument declarations */
  127.         comout(ins);             
  128.         if (header && !decl) printf("%s",ins);
  129.  
  130.     } while (lastlin);    /*  = 0 if last line */
  131.  
  132. }
  133.  
  134. /* skip this line ? */
  135.  
  136. skipline()
  137. {
  138. char c;
  139.     c = ins[curchar];
  140.  
  141.     if (c == '\0') return(TRUE);    /* end of line */
  142.  
  143.     else if (c == '#')            /* skip macro defs */
  144.         if (curchar < 5)    /* at beginning of line */
  145.             if (!strcmp("define",&ins[curchar+1])) 
  146.                 return(TRUE); 
  147.  
  148.     else return(FALSE);            /* no */
  149.  
  150. }
  151.  
  152.  
  153. /* skip characters quoted (for instance '}' would throw off level count */
  154.  
  155. quotes()
  156. {  
  157.     if (flowchar(ins[curchar]))        /* test critical chars only */
  158.         if (ins[curchar+1] == '\047')   /* next char single quote? */
  159.         if (curchar+2 < 100)        /* don't pass end of string */
  160.             curchar = curchar + 2; /* skip past quote */
  161. }
  162.  
  163.  
  164. /* return TRUE if entering comment, FALSE if exiting */
  165.  
  166. comment(incom)
  167. int incom;
  168. {
  169.     if (ins[curchar] == '/') {
  170.         if (ins[curchar+1] == '*') 
  171.             if (curchar + 1 < 100)    /* stay within string */ 
  172.                 return(TRUE);
  173.         else if (ins[curchar-1] == '*')
  174.             if (curchar - 1 >= 0)   /* stay within string */
  175.                 return(FALSE);
  176.     }
  177.     else return(incom);  /* unchanged */
  178. }
  179.  
  180.  
  181. /* look back from position n in string.  called with n indicating '('.
  182.    determine function name  */
  183.  
  184. lookbak(n)
  185. int n;
  186. {
  187.     int i;
  188.  
  189.     while (!ischar(ins[n])) {
  190.         if (n == 0) break;
  191.         --n;
  192.     }
  193.  
  194.     /* find leading blank */
  195.     while (ischar(ins[n-1])) {
  196.         if (n == 0) break;
  197.         --n;
  198.     }
  199.  
  200.     /* save name */
  201.     /* include variable declarations if module declaration */
  202.  
  203.     i = 0;
  204.     if (level == 0) {
  205.         while (ins[n])             /* full line if declaration */
  206.             name[i++] = ins[n++];
  207.     }
  208.     else {
  209.         while (ischar(ins[n]))      /* function call within function */
  210.             name[i++] = ins[n++];
  211.     }
  212.  
  213.     name[i] = '\0';
  214.  
  215.     comout(name);    /* remove comment from name string */
  216.         
  217. }
  218.  
  219.  
  220. /* terminate string at comment */
  221.  
  222. comout(s)
  223. char *s;
  224. {
  225. char c;    
  226.     
  227.     while(c = *s++) 
  228.         if (c == '/')
  229.             if (*s == '*') {
  230.                 --s;
  231.                 *s++ = '\n';
  232.                 *s = '\0';
  233.                 break;
  234.             }
  235.  
  236. }
  237.  
  238.  
  239.  
  240. /* display module name with indentation according to { level */
  241. /* returns 0 if not module, 1 if call within module, 2 if    */
  242. /* module declaration  */
  243.  
  244. modname()
  245. {
  246.     int j;
  247.  
  248.     if (unreserved()) {        /* test if builtin like while */
  249.             if (level == 0) {
  250.             printf("\n\n\n");
  251.             printf("**\n");
  252.             comout(ins);
  253.             printf("%s",ins);
  254.             return(2);
  255.                 }
  256.         else {
  257.             printf("\n");
  258.             for (j=0; j < level; ++j) 
  259.                 putchar('\t');
  260.             printf("%s()",name);
  261.             return(1);
  262.         }
  263.         }
  264.     return(0);
  265.     
  266. }
  267.  
  268. /* test for names that are operators not functions */
  269.  
  270. unreserved()
  271. {
  272.  
  273.     if (!strcmp(name,"return")) return(0);
  274.     else if (!strcmp(name,"if")) return(0);
  275.     else if (!strcmp(name,"while")) return(0);
  276.     else if (!strcmp(name,"for")) return(0);
  277.     else if (!strcmp(name,"switch")) return(0);
  278.  
  279.     else return(1);
  280.  
  281. }
  282.  
  283.  
  284. /* test if character is one that program tracks */
  285.  
  286. flowchar(c)
  287. char c;
  288. {
  289.     if (c == '{' || c == '}' || c == '\"') return(TRUE);
  290.     else return(FALSE);
  291.     
  292.  
  293.  
  294. /* test for character */
  295.  
  296. ischar(c)
  297. char c;
  298. {
  299.     if (isalpha(c) || isdigit(c)) return(TRUE);
  300.     else return(FALSE);
  301. }
  302.  
  303.  
  304. /* read a line of source */
  305.  
  306. fgets()
  307. {
  308.     char ch, *s;
  309.     s = ins;
  310.     while ((ch = getc(fptr)) != EOF) {
  311.         *s++ = ch;
  312.         if (ch == '\n') {
  313.             *s = '\0';
  314.             return(TRUE);
  315.         }
  316.     }
  317.     *s = '\0';
  318.     return(FALSE);
  319.  
  320. }    
  321.     
  322.  
  323.  
  324.